<?php
namespace App;

use App\Controller\UserController;
use App\Library\System\App;
use App\Library\System\Config;
use App\Library\System\Model\AppModel;
use App\Library\System\Model\CacheModel;
use App\Library\System\Model\UserModel;
use App\Library\System\Sub\Auth;
use App\Library\Compiler\Yaml\Spyc;
use Zend\Mvc\ModuleRouteListener;
use Zend\Http\Response;
use Zend\Mvc\MvcEvent;
use Zend\XmlRpc\Server\Cache;

class Module
{
    /**
     * Zend Framework Bootstrap
     *
     * @param \Zend\Mvc\MvcEvent $e
     *
     * @return type
     */
    public function onBootstrap(MvcEvent $e)
    {
        $cache = new CacheModel();
        $config = Config::getInstance();
        $content = $cache->getCache('html', $cache->getCacheHash());

        # Using cache
        if (($content) && $config->isProduction()) {

            $response = $e->getResponse();
            $response->setStatusCode(Response::STATUS_CODE_200);

            # Using GZIP Compression
            if ($cache->canCompress()) {
                header('Content-Encoding: gzip');
                $content = gzencode($content->content, 9);
            }

            $response->setContent($content);

            $stopCallBack = function ($event) use ($response) {
                $event->stopPropagation();

                return $response;
            };

            //Attach the "break" as a listener with a high priority
            $e->getApplication()->getEventManager()->attach(MvcEvent::EVENT_ROUTE, $stopCallBack, -10000);

            return $response;
        } else {
            $eventManager = $e->getApplication()->getEventManager();
            $eventManager->attach("finish", array($this, "createCache"), 100);
            $moduleRouteListener = new ModuleRouteListener();
            $moduleRouteListener->attach($eventManager);
        }
    }

    /**
     * Create cache
     *
     * @param MvcEvent $e
     */
    public function createCache($e)
    {
        if (isset($_SESSION['cache'])&&($_SESSION['cache'])) {
            $response = $e->getResponse();
            $content = $response->getBody();
            $response->setContent($content);
            $content = preg_replace('#(?ix)(?>[^\S ]\s*|\s{2,})(?=(?:(?:[^<]++|<(?!/?(?:textarea|pre)\b))*+)(?:<(?>textarea|pre)\b|\z))#', '', $content);
            $cache = new CacheModel();
            $cache->createCache('html', $cache->getCacheHash(), $content);
        }
    }

    public function getAutoloaderConfig()
    {
        return array(
            'Zend\Loader\StandardAutoloader' => array(
                'namespaces' => array(
                    __NAMESPACE__ => __DIR__ . '/src/' . __NAMESPACE__,
                ),
            ),
        );
    }

    /**
     * Get service
     *
     * @return type
     */
    public function getServiceConfig()
    {
        return array(
            'factories' => array(
                'App\Controller\UserController' => function($sm) {
                        $controller = new UserController();
                        return $controller;
                }
            ),
        );
    }

    /**
     * Get configuration
     *
     * @return type
     */
    public function getConfig()
    {
        $config = $this->changeLanguage(include __DIR__ . '/config/module.config.php');

        $app_config = __DIR__ . '/config/app.yaml';

        # Load Configuration
        if (!isset($_SESSION['config'])) {
            $_SESSION['config'] = Spyc::YAMLLoad($app_config);
        }

        # Set default language
        if (!isset($_SESSION['app_lang'])) {
            $_SESSION['app_lang'] = $config['translator']['locale'];
        }


        $this->autoLogin();

        return $config;
    }

    /**
     * Automatic login
     *
     * @return type
     */
    public function autoLogin()
    {
        $cache = new CacheModel();

        $auth = new Auth();
        if ($auth->login) return;

        $id = App::cookie('id');
        if (!is_numeric($id)) return;

        $user = new UserModel($id);
        if (!$user->isValid()) return;

        // Compare signature 
        $client_signature = App::cookie('signature');
        $server_signature = $user->getSignature();

        if ($client_signature === $server_signature) {
            $app = AppModel::getInstance();
            $app->saveUser($user->id, $user->name);
        }
    }

    public function changeLanguage($config)
    {
        if (isset($_POST['app_lang'])) {
            $_SESSION['app_lang'] = $_POST['app_lang'];
        }

        if (isset($_SESSION['app_lang'])) {
            $config['translator']['locale'] = $_SESSION['app_lang'];
        }

        return $config;
    }
}
